﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Reviewer.Entities.Services;
using Reviewer.Business;
using Reviewer.Entities;
using AjaxControlToolkit;
using System.Globalization;
using System.Web.UI.HtmlControls;

public partial class CMSV2_Controls_RelationPicker : System.Web.UI.UserControl
{
    public bool GameGroupByFormat { get { return this.uiGameCblGrouping.Items.FindByValue("1").Selected; } set { this.uiGameCblGrouping.Items.FindByValue("1").Selected = value; } }
    public bool GameGroupByGenre { get { return this.uiGameCblGrouping.Items.FindByValue("2").Selected; } set { this.uiGameCblGrouping.Items.FindByValue("2").Selected = value; } }
    public bool GameGroupByFirstLetter { get { return this.uiGameCblGrouping.Items.FindByValue("3").Selected; } set { this.uiGameCblGrouping.Items.FindByValue("3").Selected = value; } }
    public bool GameAllowSelection { get; set; }
    public bool GameShowAllFormats { get; set; }

    public event RelationIsItemSelectedDelegate IsRelationSelected;
    public event RelationItemIsSelectedDelegate RelationSelected;
    public event RelationItemIsSelectedDelegate RelationUnSelected;
    
    public event RelationPrefilterGames GamePrefiter;

    public Type CurrentType { get; set; }
    public Guid CurrentId { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            GameDataBind();
        }
    }

    #region Game
    private void GameDataBind()
    {
        if (this.GameAllowSelection)
        {
            this.uiGameTwAllGames.Nodes.Clear();

            TreeNode rootNode = new TreeNode("Alle spil", "[ROOT]");
            rootNode.ShowCheckBox = false;
            rootNode.ChildNodes.Add(new TreeNode("-", "-"));
            this.uiGameTwAllGames.Nodes.Add(rootNode);

            rootNode.Expand();
        }
        else
        {
            this.uiGamePnlSelectGames.Visible = false;
        }
    }

    protected void uiTwGames_TreeNodeCheckChanged(object sender, TreeNodeEventArgs e)
    {
        string[] valueParts = e.Node.Value.Split('|');
        if (e.Node.Checked && this.RelationSelected != null)
        {
            RelationSelected(typeof(Game), int.Parse(valueParts[0]), new Guid(valueParts[1]));
        }
        else if (this.RelationUnSelected != null)
        {
            RelationUnSelected(typeof(Game), int.Parse(valueParts[0]), new Guid(valueParts[1]));
        }
    }

    protected void uiTwGames_TreeNodeExpanded(object sender, TreeNodeEventArgs e)
    {
        bool groupByFormat = false;
        bool groupByGenre = false;
        bool groupByFirstLetter = false;
        foreach (ListItem item in this.uiGameCblGrouping.Items)
        {
            switch (item.Value)
            {
                case "1":
                    groupByFormat = item.Enabled && item.Selected;
                    break;
                case "2":
                    groupByGenre = item.Enabled && item.Selected;
                    break;
                case "3":
                    groupByFirstLetter = item.Enabled && item.Selected;
                    break;
            }
        }

        if (e.Node.ChildNodes.Count != 1 || !e.Node.ChildNodes[0].Value.Equals("-"))
        {
            return;
        }

        e.Node.ChildNodes.Clear();

        if (e.Node.Value.Equals("[ROOT]"))
        {
            if (groupByFormat)
            {
                GameAddFormatNodes(e.Node);
            }
            else if (groupByGenre)
            {
                GameAddGenreNodes(e.Node);
            }
            else if (groupByFirstLetter)
            {
                GameAddFirstLetterNodes(e.Node);
            }
            else
            {
                GameAddGameNodes(e.Node);
            }
        }
        else
        {
            switch (e.Node.Value.Substring(0, 1))
            {
                case "F": //format
                    if (groupByGenre)
                    {
                        GameAddGenreNodes(e.Node);
                    }
                    else if (groupByFirstLetter)
                    {
                        GameAddFirstLetterNodes(e.Node);
                    }
                    else
                    {
                        GameAddGameNodes(e.Node);
                    }
                    break;
                case "G":
                    if (groupByFirstLetter)
                    {
                        GameAddFirstLetterNodes(e.Node);
                    }
                    else
                    {
                        GameAddGameNodes(e.Node);
                    }
                    break;
                default:
                    GameAddGameNodes(e.Node);
                    break;
            }
        }
    }

    private void GameAddFormatNodes(TreeNode parentNode)
    {
        using (IMetadataService<Format> service = ServiceFactory.GetMetadataService<Format>())
        {
            foreach (Format format in service.GetAll().OrderBy(t => t.Name))
            {
                TreeNode node = new TreeNode(format.Name, "F:" + format.Id.ToString());
                node.ShowCheckBox = false;
                node.ChildNodes.Add(new TreeNode("-", "-"));
                node.Collapse();
                parentNode.ChildNodes.Add(node);
            }
        }
    }

    private void GameAddGenreNodes(TreeNode parentNode)
    {
        using (IMetadataService<Genre> service = ServiceFactory.GetMetadataService<Genre>())
        {
            foreach (Genre genre in service.GetAll().OrderBy(t => t.Name))
            {
                TreeNode node = new TreeNode(genre.Name, "G:" + genre.Id.ToString());
                node.ShowCheckBox = false;
                node.ChildNodes.Add(new TreeNode("-", "-"));
                node.Collapse();
                parentNode.ChildNodes.Add(node);
            }
        }
    }

    private void GameAddFirstLetterNodes(TreeNode parentNode)
    {
        int formatId = -1;
        int genreId = -1;

        TreeNode pNode = parentNode;
        while (pNode.Value != "[ROOT]")
        {
            switch (pNode.Value.Substring(0, 1))
            {
                case "F":
                    formatId = int.Parse(pNode.Value.Substring(2));
                    break;
                case "G":
                    genreId = int.Parse(pNode.Value.Substring(2));
                    break;
            }
            pNode = pNode.Parent;
        }

        using (IGameService service = ServiceFactory.GameService)
        {
            IEnumerable<Game> games = service.GetAll();
            if (this.GamePrefiter != null)
            {
                games = this.GamePrefiter(games);
            }

            if (formatId > 0)
            {
                games = games.Where(t => t.Format.Equals(formatId));
            }
            if (genreId > 0)
            {
                games = games.Where(t => t.Genre.Equals(genreId));
            }

            foreach (IGrouping<String, Game> game in games.GroupBy(t => t.Title.Length > 0 ? t.Title.Substring(0, 1).ToUpperInvariant() : "<Tom>").OrderBy(t => t.Key))
            {
                TreeNode node = new TreeNode(game.Key, "L:" + game.Key);
                node.ShowCheckBox = false;
                node.ChildNodes.Add(new TreeNode("-", "-"));
                node.Collapse();
                parentNode.ChildNodes.Add(node);
            }
        }
    }

    private void GameAddGameNodes(TreeNode parentNode)
    {
        //move up the tree to get filters
        int formatId = -1;
        int genreId = -1;
        string firstLetter = "";

        TreeNode pNode = parentNode;
        while (pNode.Value != "[ROOT]")
        {
            switch (pNode.Value.Substring(0, 1))
            {
                case "F":
                    formatId = int.Parse(pNode.Value.Substring(2));
                    break;
                case "G":
                    genreId = int.Parse(pNode.Value.Substring(2));
                    break;
                case "L":
                    firstLetter = pNode.Value.Substring(2);
                    break;
            }
            pNode = pNode.Parent;
        }

        using (IGameService service = ServiceFactory.GameService)
        {
            IEnumerable<Game> games = service.GetAll();
            if (this.GamePrefiter != null)
            {
                games = this.GamePrefiter(games);
            }

            if (formatId > 0)
            {
                games = games.Where(t => t.Format.Equals(formatId));
            }
            if (genreId > 0)
            {
                games = games.Where(t => t.Genre.Equals(genreId));
            }
            if (!String.IsNullOrEmpty(firstLetter))
            {
                games = games.Where(t => t.Title.ToUpperInvariant().StartsWith(firstLetter.ToUpperInvariant(), StringComparison.Ordinal));
            }

            ICollection<Format> formats = null;
            if (formatId < 0)
            {
                using (IMetadataService<Format> formatService = ServiceFactory.GetMetadataService<Format>())
                {
                    formats = formatService.GetAll();
                }
            }

            foreach (Game game in games.OrderBy(t => t.Title))
            {
                Format formatItem = null;
                if (formatId < 0)
                {
                    formatItem = formats.FirstOrDefault(t => t.Id.Equals(game.Format));
                }

                TreeNode node = new TreeNode(game.Title + ((formatId < 0) ? " (" + (formatItem == null ? "Ukendt format" : formatItem.Name) + ")" : ""), game.Id.ToString() + "|" + game.GameId.ToString());
                node.ShowCheckBox = true;
                if (IsRelationSelected != null)
                {
                    node.Checked = IsRelationSelected(typeof(Game), game.Id, game.GameId);
                }

                parentNode.ChildNodes.Add(node);

                if (node.Checked)
                {
                    parentNode.Expand();
                }
            }
        }

    }

    protected void uiGameCblGrouping_SelectedIndexChanged(object sender, EventArgs e)
    {
        this.GameDataBind();
    }
    #endregion

    protected void uiMenu_MenuItemClick(object sender, MenuEventArgs e)
    {
        this.uiMvPickings.ActiveViewIndex = int.Parse(e.Item.Value);
    }

}
